#include<iostream>
#include<Windows.h>
#include <string>
#include <windowsx.h>
#include <tchar.h>
#include <commdlg.h>
#include <stdlib.h>
#include <time.h>
using namespace std;


int CharToMass(PBYTE pbFile,unsigned int a[],DWORD dwBytesInBlock,int x) 
{
	char s[6];
	int j = 0;
	int k=x;
	bool first = false;
	if (x>-1)
	{
		first = true;
	}
	for (int i =0;i<dwBytesInBlock;i++)
	{
		if (pbFile[i] == ' ' )
		{			
			s[j] = '\0';
			x = atoi(s);
			if (first)
			{
				first = false;
				x = k * 10^(j) + x;
			}			
			j=0;
			a[x]++;
		}
		else 
		{
			s[j] = pbFile[i];
			j++;
		}
	}

	if (pbFile[dwBytesInBlock-1]!=' ' )
	{
		s[j] = '\0';
		x = atoi(s);
		return x;
	}
	return -1;
	
}
int MassToChar(PBYTE pbFile,unsigned int a[],DWORD dwBytesInBlock,int *i,int *o,int *j)//return >=0 if well done
{	
	char buffer [6];
	int pos=0;
	for ((*i);(*i)<=10000;(*i)++)
	{
		a[(*i)]-=(*o);
		if (a[(*i)] > 0)
		{
			itoa ((*i),buffer,10);
			for ((*o)=0 ;(*o)<a[(*i)];(*o)++)
			{
				while ((buffer[(*j)] != '\0')&&(pos < dwBytesInBlock))
				{
					pbFile[pos] = buffer[(*j)];
					pos++;
					(*j)++;
				}
				if (pos>=dwBytesInBlock)
				{
					return 0;
				}
				(*j)=0;
				pbFile[pos] = ' ';
				pos++;
			}
			(*o)=0;
			a[(*i)]=0;
		}
	}
	return 0;
}

int main ()
{
	clock_t t0 = clock();
	SYSTEM_INFO sinf;
	GetSystemInfo(&sinf); 
	LPCWSTR pszFileName = L"C:\\testdir\\test1.txt";
	LPCWSTR f2 = L"C:\\testdir\\test00.txt";
	HANDLE hfile =  CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	HANDLE mfile = CreateFileMapping(hfile,NULL,PAGE_READWRITE,0,0,NULL);
	DWORD dwFileSizeHigh;
    __int64 qwFileSize = GetFileSize(hfile, &dwFileSizeHigh);
	__int64 size = qwFileSize;
	qwFileSize += (((__int64) dwFileSizeHigh) << 32); 
	CloseHandle(hfile);
    __int64 qwFileOffset = 0;
	__int64 qwNumOf0s = 0;
	int max = 10000;
	unsigned int a[10000];
	for (int i =0;i<max;i++)
	{
		a[i]=0;
	}
	int x=-1;

	while (qwFileSize > 0) 
	{
		DWORD dwBytesInBlock = sinf.dwAllocationGranularity; 
        if (qwFileSize < sinf.dwAllocationGranularity)
		{
            dwBytesInBlock = (DWORD)qwFileSize; 
		}
		PBYTE pbFile = (PBYTE)MapViewOfFile(mfile, FILE_MAP_READ,(DWORD) (qwFileOffset >> 32),(DWORD) (qwFileOffset & 0xFFFFFFFF),dwBytesInBlock);

		x = CharToMass(pbFile,a,dwBytesInBlock,x);
		if (x<-1)
		{
			//Wrong format of including of file
			return 0;
		}
		UnmapViewOfFile(pbFile);
        qwFileOffset += dwBytesInBlock;
        qwFileSize -= dwBytesInBlock; 
    }
	CloseHandle(mfile);
	if (x>=0)
	{
		a[x]++;
	}

	qwFileOffset = 0;
	qwNumOf0s = 0;
	qwFileSize = size;
	hfile = CreateFile(f2, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL, NULL);
	mfile = CreateFileMapping(hfile, NULL, PAGE_READWRITE, 0, qwFileSize, NULL); 
	qwFileSize += (((__int64) dwFileSizeHigh) << 32); 
	x=0;
	int i=0;
	int j=0;
	int o=0;
	while (qwFileSize > 0) 
	{
		DWORD dwBytesInBlock = sinf.dwAllocationGranularity; 
        if (qwFileSize < sinf.dwAllocationGranularity)
		{
            dwBytesInBlock = (DWORD)qwFileSize; 
		}
		PBYTE pbFile = (PBYTE)MapViewOfFile(mfile, FILE_MAP_WRITE,(DWORD) (qwFileOffset >> 32),(DWORD) (qwFileOffset & 0xFFFFFFFF),dwBytesInBlock);
		x = MassToChar(pbFile,a,dwBytesInBlock,&i,&o,&j);
		if (x<-1)
		{
			return 0;
		}
		FlushViewOfFile(pbFile,dwBytesInBlock);
		UnmapViewOfFile(pbFile);
        qwFileOffset += dwBytesInBlock;
        qwFileSize -= dwBytesInBlock; 
    }
	clock_t t1 = clock();
	cout << "time: " << (double)(t1 - t0) / CLOCKS_PER_SEC<<" seconds" << endl;
	
	return 0;
}